package com.yxy.ms.manager.web;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.ParseException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.yxy.ms.manager.common.Common;
import com.yxy.ms.manager.common.Results;
import com.yxy.ms.manager.entity.po.A22UrlMapping;
import com.yxy.ms.manager.entity.po.A23DataFile;
import com.yxy.ms.manager.entity.po.A36OrganTransform;
import com.yxy.ms.manager.entity.po.A36TollIntervalInfo;
import com.yxy.ms.manager.entity.po.ClearDataTemp;
import com.yxy.ms.manager.entity.po.ClearErrorInfo;
import com.yxy.ms.manager.entity.po.ClearMessageInfo;
import com.yxy.ms.manager.entity.po.ClearMessageInfoKey;
import com.yxy.ms.manager.entity.po.ErrorData;
import com.yxy.ms.manager.entity.po.M21DataSendRecord;
import com.yxy.ms.manager.service.MonitorService;

@RestController
@RequestMapping(value = "/monitor/")
public class MonitorDataController {

    private static final Logger logger = LoggerFactory.getLogger(MonitorDataController.class);

    @Autowired
    MonitorService monitorService;

    /**
     * <函数描述>ErrorData异常信息数据
     * 
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "getErrorDataList", method = RequestMethod.POST)
    public Results getErrorDataList(@RequestBody String data) {
        Page<ErrorData> list = monitorService.findErrorDataList(conditional(data));
        return Common.results200(getPageData(list));
    }

    /**
     * <函数描述>A36OrganTransfer信息列表
     * 
     * @param data
     *            请求参数
     * @return
     */
    @RequestMapping(value = "getA36List", method = RequestMethod.POST)
    public Results getA36List(@RequestBody String data) {
        Page<A36OrganTransform> list = monitorService.findA36OrganTransformList(conditional(data));
        return Common.results200(getPageData(list));
    }

    /**
     * <函数描述>收费单元列表信息
     * 
     * @param data
     *            请求参数
     * @return
     */
    @RequestMapping(value = "getA36TollIntervalInfo", method = RequestMethod.POST)
    public Results getA36TollIntervalInfo(@RequestBody String data) {
        Page<A36TollIntervalInfo> list = monitorService.findA36TollIntervalInfo(conditional(data));
        return Common.results200(getPageData(list));
    }

    /**
     * <函数描述>查找A22地址列表信息
     * 
     * @param data
     *            请求参数
     * @return
     */
    @RequestMapping(value = "getA22UrlMapping", method = RequestMethod.POST)
    public Results getA22UrlMapping(@RequestBody String data) {
        Page<A22UrlMapping> list = monitorService.findA22UrlMapping(conditional(data));
        return Common.results200(getPageData(list));
    }

    /**
     * <函数描述>查找A23地址列表信息
     * 
     * @param data
     *            请求参数
     * @return
     */
    @RequestMapping(value = "getA23DataFile", method = RequestMethod.POST)
    public Results getA23DataFile(@RequestBody String data) {
        Page<A23DataFile> list = monitorService.findA23DataFile(conditional(data));
        return Common.results200(getPageData(list));
    }

    /**
     * <函数描述>查找M21
     * 
     * @param data
     *            请求参数
     * @return
     */
    @RequestMapping(value = "getM21DataSendRecord", method = RequestMethod.POST)
    public Results getM21DataSendRecord(@RequestBody String data) {
        Page<M21DataSendRecord> list = monitorService.findgetM21DataSendRecord(conditional(data));
        return Common.results200(getPageData(list));
    }

    /**
     * <函数描述>A22地址详细信息
     * 
     * @param data
     *            请求参数
     * @return
     */
    @RequestMapping(value = "getA22UrlMappingEdit", method = RequestMethod.POST)
    public Results getA22UrlMappingEdit(@RequestBody String data) {
        return Common.results200(monitorService.getA22UrlMappingEdit(conditional(data).getString("id")));
    }

    @RequestMapping(value = "saveA22UrlMapping", method = RequestMethod.POST)
    public Results saveA22UrlMapping(@RequestBody String data) {
        try {
            monitorService.saveA22UrlMapping(conditional(data, A22UrlMapping.class));
        } catch (Exception ex) {
            return Common.results400("操作出错");
        }
        return Common.results200();
    }

    /**
     * <函数描述>A22数据类型下拉列表
     * 
     * @return
     */
    @RequestMapping(value = "loadA22UrlMappingDataType", method = RequestMethod.GET)
    public Results loadA22UrlMappingDataType() {
        return Common.results200(monitorService.findA22UrlMappingDataType());
    }

    /**
     * <函数描述>导出数据
     * 
     * @param request
     *            请求
     * @param response
     *            响应
     * @return
     */
    @RequestMapping(value = "exportErrorDataFile", method = RequestMethod.POST)
    public void exportFile(HttpServletRequest request, HttpServletResponse response) {
        File file = new File(System.getProperty("user.home"), "ERROR_DATA_" + System.currentTimeMillis() + ".txt");
        // 生成文件
        FileOutputStream outputStream = null;
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            String data = IOUtils.toString(request.getInputStream(), "utf-8");
            Page<ErrorData> list = monitorService.findErrorDataList(conditional(data));
            String content = null;
            if (list != null && !list.isEmpty()) {
                content = JSON.toJSONString(list);
            }
            if (content == null) {
                content = "暂无数据";
            }
            outputStream = new FileOutputStream(file);
            IOUtils.copy(IOUtils.toInputStream(content), outputStream);

        } catch (Exception ex) {
            throw new RuntimeException("生成要导出的文件失败," + ex);
        } finally {
            IOUtils.closeQuietly(outputStream);
        }

        // 导出文件
        InputStream inputStream = null;
        OutputStream os = null;
        try {
            response.setContentLength((int)file.length());
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition",
                "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
            os = response.getOutputStream();
            // 加载文件输入流
            inputStream = new FileInputStream(file);
            IOUtils.copy(inputStream, os);
        } catch (Exception ex) {
            throw new RuntimeException("导出出错," + ex);
        } finally {
            IOUtils.closeQuietly(inputStream);
            IOUtils.closeQuietly(os);
            FileUtils.deleteQuietly(file);
        }
    }

    /**
     * <函数描述>下载文件
     * 
     * @param request
     *            请求
     * @param response
     *            响应
     * @return
     */
    @RequestMapping(value = "downLoadFile", method = RequestMethod.GET)
    public Results downLoadFile(HttpServletRequest request, HttpServletResponse response) {
        String queryString = request.getQueryString();
        if (StringUtils.isBlank(queryString)) {
            return Common.results400("下载出错，无参数");
        }

        String query = new String(Base64.getUrlDecoder().decode(queryString));
        String[] params = new String[2];

        Pattern pattern = Pattern.compile("id=([^&]*)");
        Matcher matcher = pattern.matcher(query);
        if (matcher.find()) {
            params[0] = StringUtils.replaceAll(matcher.group(), "^id=", "");
        }

        pattern = Pattern.compile("type=(\\w)*$");
        matcher = pattern.matcher(query);
        if (matcher.find()) {
            params[1] = StringUtils.replaceAll(matcher.group(), "^type=", "");
        }

        ErrorData errorData = monitorService.getById(params[0]);
        if (errorData == null) {
            return Common.results400("下载出错，下载数据不存在");
        }

        if (StringUtils.isBlank(errorData.getFileName())) {
            errorData.setFileName(params[0] + ".json");
        }

        OutputStream os = null;
        try {
            String content = null;
            String fileName = null;
            if (params[1].equals("file")) {
                if (!StringUtils.isBlank(errorData.getDataJson())) {
                    fileName = errorData.getFileName();
                    content = JSON.toJSONString(JSON.parse(errorData.getDataJson()), SerializerFeature.PrettyFormat);
                }
            } else {
                fileName = errorData.getFileName() + "_ERROR.txt";
                content = errorData.getErrDesc();
            }

            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            os = response.getOutputStream();
            IOUtils.copy(IOUtils.toInputStream(content, "UTF-8"), os);

        } catch (IOException e) {
            return Common.results400("下载出错," + e);
        } finally {
            IOUtils.closeQuietly(os);
        }

        return null;

    }

    /**
     * <函数描述>下载文件
     * 
     * @param request
     *            请求
     * @param response
     *            响应
     * @return
     */
    @RequestMapping(value = "downLoadClearResponseFile", method = RequestMethod.GET)
    public Results downLoadClearInfoFile(HttpServletRequest request, HttpServletResponse response) {
        String queryString = request.getQueryString();
        if (StringUtils.isBlank(queryString)) {
            return Common.results400("下载出错，无参数");
        }

        String query = new String(Base64.getUrlDecoder().decode(queryString));
        String[] params = new String[2];

        Pattern pattern = Pattern.compile("id=([^&]*)");
        Matcher matcher = pattern.matcher(query);
        if (matcher.find()) {
            params[0] = StringUtils.replaceAll(matcher.group(), "^id=", "");
        }

        pattern = Pattern.compile("type=(\\w)*$");
        matcher = pattern.matcher(query);
        if (matcher.find()) {
            params[1] = StringUtils.replaceAll(matcher.group(), "^type=", "");
        }

        ClearMessageInfo clearMessageInfo = null;
        try {
            clearMessageInfo = monitorService.getClearMessageInfo(new ClearMessageInfoKey(params[0],
                Integer.parseInt(params[1]), DateUtils.parseDate(params[2], "yyyy-mm-dd HH:mm:ss")));
            if (clearMessageInfo == null) {
                return Common.results400("下载出错，下载数据不存在");
            }
        } catch (NumberFormatException e1) {
            e1.printStackTrace();
        } catch (ParseException e1) {
            e1.printStackTrace();
        }

        OutputStream os = null;
        InputStream input = null;
        File file = null;
        try {
            String fileName = null;
            if (params[1].equals("file")) {
                if (!StringUtils.isBlank(clearMessageInfo.getFilePath())) {
                    fileName = clearMessageInfo.getFileName();
                    file = new File(clearMessageInfo.getFilePath());
                }
            }

            if (file != null && file.exists()) {
                input = new FileInputStream(file);
            } else {
                input = IOUtils.toInputStream("目录[ " + clearMessageInfo.getFilePath() + "]下未找到文件", "UTF-8");
            }
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            os = response.getOutputStream();
            IOUtils.copy(input, os);
        } catch (IOException e) {
            return Common.results400("下载出错," + e);
        } finally {
            IOUtils.closeQuietly(os);
        }

        return null;

    }

    /**
     * <函数描述>清分临时表数据
     * 
     * @return
     */
    @RequestMapping(value = "getTempDataList", method = RequestMethod.POST)
    public Results getTempDataList(@RequestBody String data) {
        Page<ClearDataTemp> list = monitorService.findClearDataTempList(conditional(data));
        return Common.results200(getPageData(list));
    }

    /**
     * <函数描述>清分临时表数据
     * 
     * @return
     */
    @RequestMapping(value = "removeClearTempData", method = RequestMethod.POST)
    public Results removeClearTempData(@RequestBody String data) {
        monitorService.deleteClearTempData(conditional(data).getLong("mid"),
            conditional(data).getInteger("transTypeCode"));
        return Common.results200();
    }

    /**
     * <函数描述>清分信息表数据
     * 
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "getMessageInfoList", method = RequestMethod.POST)
    public Results getMessageInfoList(@RequestBody String data) {
        Page<ClearMessageInfo> list = monitorService.findClearMessageInfoList(conditional(data));
        return Common.results200(getPageData(list));
    }

    /**
     * <函数描述>清分错误信息表数据
     * 
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "getClearErrorInfoList", method = RequestMethod.POST)
    public Results getClearErrorInfoList(@RequestBody String data) {
        Page<ClearErrorInfo> list = monitorService.getClearErrorInfoList(conditional(data));
        return Common.results200(getPageData(list));
    }

    /**
     * <函数描述>加载
     * 
     * @return
     */
    @RequestMapping(value = "loadTransTypeCodeDropList", method = RequestMethod.GET)
    public Results loadTransTypeCodeDropList() {
        return Common.results200(monitorService.loadTransTypeCodeDropList());
    }

    protected JSONObject conditional(String data) {
        JSONObject root = JSON.parseObject(data);
        JSONObject page = root.getJSONObject("page");
        JSONObject params = root.getJSONObject("params");

        if (page != null) {
            PageHelper.startPage(null != page.getInteger("pageIndex") ? page.getInteger("pageIndex") : 1,
                null != page.getInteger("pageSize") ? page.getInteger("pageSize") : 10);
            PageHelper.orderBy(StringUtils.isEmpty(page.getString("orderBy")) ? "" : page.getString("orderBy"));
        }

        return params;
    }

    @SuppressWarnings("unchecked")
    protected <T> T conditional(String data, Class<?> classType) {
        JSONObject root = JSON.parseObject(data);
        JSONObject params = root.getJSONObject("params");
        return (params != null ? (T)params.toJavaObject(classType) : null);
    }

    /**
     * <函数描述>获取入或出口交易信息
     * 
     * @return
     */
    @RequestMapping(value = "getTransGantryEtc", method = RequestMethod.POST)
    public Results getTransGantryEtc(@RequestBody String data) {
        JSONObject root = JSON.parseObject(data);
        JSONObject params = root.getJSONObject("params");
        return Common.results200(monitorService.getTransGantryEtcById(params.getLong("mid")));
    }

    /**
     * <函数描述>获取入或出口交易信息
     * 
     * @return
     */
    @RequestMapping(value = "getTransExit", method = RequestMethod.POST)
    public Results getTransExit(@RequestBody String data) {
        JSONObject root = JSON.parseObject(data);
        JSONObject params = root.getJSONObject("params");
        return Common.results200(monitorService.getTransExitById(params.getLong("mid")));
    }

    protected Map<String, Object> getPageData(Page<?> page) {
        Map<String, Object> result = new HashMap<String, Object>();
        // 总记录数
        result.put("total", page.getTotal());
        // 总页数
        result.put("pages", page.getPages());
        // 每页记录数
        result.put("pageSize", page.getPageSize());
        // 当前页码
        result.put("pageNum", page.getPageNum());
        // 结果
        result.put("rows", page.getResult());
        return result;
    }

}
